package demoMod.moduploader.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.codedisaster.steamworks.*;
import demoMod.gdxform.core.AbstractAction;
import demoMod.gdxform.enums.GFrameWindowMode;
import demoMod.gdxform.enums.GFrameWindowStyle;
import demoMod.gdxform.ui.GFrame;
import demoMod.gdxform.ui.GLabel;
import demoMod.moduploader.localization.LocalizedStrings;
import demoMod.moduploader.model.ModInfo;
import demoMod.moduploader.model.ModUploadCallback;

import java.io.File;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;

public class ModUploadWindow extends GFrame {
    public static final String ID = "ModUploadWindow";
    private final SteamUGC workshop;
    private final Timer timer = new Timer(true);
    private final GLabel lblStatus;
    private final GLabel lblProgress;

    public ModUploadWindow(BitmapFont bannerFont, ModDisplayItem modDisplayItem, boolean isUpdate) {
        super(Gdx.graphics.getWidth() * 0.25F, Gdx.graphics.getHeight() * 0.35F - 10, Gdx.graphics.getWidth() * 0.5F, Gdx.graphics.getHeight() * 0.3F, bannerFont, GFrameWindowStyle.NONE, false);
        setId(ID);
        setWindowMode(GFrameWindowMode.MODAL);
        List<String> strings = LocalizedStrings.getStrings("ModInfoWindow");
        setTitle(isUpdate ? strings.get(7) : strings.get(6));
        GLabel lblNotice = new GLabel(getWidth() * 0.4F, getHeight() * 0.7F, 300.0F, 30.0F, bannerFont);
        lblNotice.setText(strings.get(9));
        addElement(lblNotice);
        lblStatus = new GLabel(getWidth() * 0.4F, getHeight() * 0.5F, 300.0F, 30.0F, bannerFont);
        lblStatus.setText(strings.get(10));
        addElement(lblStatus);

        lblProgress = new GLabel(getWidth() * 0.4F, getHeight() * 0.4F, 300.0F, 30.0F, bannerFont);
        lblProgress.setText(String.format(strings.get(18), 0.0F));
        addElement(lblProgress);

        SteamUGCCallback callback = new ModUploadCallback(modDisplayItem);
        workshop = new SteamUGC(callback);
        if (modDisplayItem.getModInfoCache().steamPublishedID == null) {
            workshop.createItem(646570, SteamRemoteStorage.WorkshopFileType.Community);
        } else {
            updateItemInfo(modDisplayItem);
        }
    }

    public void updateItemInfo(ModDisplayItem modDisplayItem) {
        ModInfo config = modDisplayItem.getModInfoCache();
        SteamPublishedFileID fileID = new SteamPublishedFileID(Long.parseLong(config.steamPublishedID));
        SteamUGCUpdateHandle updateHandle = workshop.startItemUpdate(646570, fileID);
        if (!config.title.isEmpty()) {
            this.workshop.setItemTitle(updateHandle, config.title);
        }

        if (!config.description.isEmpty()) {
            this.workshop.setItemDescription(updateHandle, config.description);
        }

        File contentPath = modDisplayItem.getModUploadItem().getModContentFolder();

        if (Objects.requireNonNull(contentPath.listFiles()).length > 0) {
            this.workshop.setItemContent(updateHandle, contentPath.getAbsolutePath());
        }

        File previewPath = modDisplayItem.getModUploadItem().getModImage();

        if (previewPath.exists()) {
            this.workshop.setItemPreview(updateHandle, previewPath.getAbsolutePath());
        }

        if (!config.visibility.isEmpty()) {
            SteamRemoteStorage.PublishedFileVisibility publishedFileVisibility = null;
            if (config.visibility.startsWith("private")) {
                publishedFileVisibility = SteamRemoteStorage.PublishedFileVisibility.Private;
            }
            if (config.visibility.startsWith("public")) {
                publishedFileVisibility = SteamRemoteStorage.PublishedFileVisibility.Public;
            }
            if (config.visibility.startsWith("friend")) {
                publishedFileVisibility = SteamRemoteStorage.PublishedFileVisibility.FriendsOnly;
            }

            if (publishedFileVisibility != null) {
                this.workshop.setItemVisibility(updateHandle, publishedFileVisibility);
            }
        }

        if (config.tags.length > 0) {
            this.workshop.setItemTags(updateHandle, config.tags);
        }

        this.workshop.submitItemUpdate(updateHandle, config.changeNote);

        List<String> strings = LocalizedStrings.getStrings("ModInfoWindow");
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                SteamUGC.ItemUpdateInfo info = new SteamUGC.ItemUpdateInfo();
                SteamUGC.ItemUpdateStatus status = ModUploadWindow.this.workshop.getItemUpdateProgress(updateHandle, info);
                switch (status) {
                    case Invalid:
                        lblStatus.setText(strings.get(17));
                        closeLater();
                        break;
                    case PreparingConfig:
                        lblStatus.setText(strings.get(10));
                        break;
                    case PreparingContent:
                        lblStatus.setText(strings.get(11));
                        break;
                    case UploadingContent:
                        lblStatus.setText(strings.get(12));
                        break;
                    case UploadingPreviewFile:
                        lblStatus.setText(strings.get(13));
                        break;
                    case CommittingChanges:
                        lblStatus.setText(strings.get(14));
                        break;
                }
                float progress = (info.getBytesProcessed() / (float) info.getBytesTotal()) * 100.0F;
                lblProgress.setText(String.format(strings.get(18), Float.isNaN(progress) ? 0.0F : progress));
            }
        }, 1000L, 1000L);
    }

    public void changeStatusText(String s) {
        lblStatus.setText(s);
    }

    public void closeLater() {
        timer.cancel();
        actionManager.addToSequenceBot(new AbstractAction.Builder().setDuration(5.0F).setActionBody(dur -> {
            if (dur < 0) {
                performCloseAction();
            }
            return dur < 0;
        }).build());
    }
}
